(function($){  
    var canvasDom = $('<canvas style="display:none;"></canvas>').get(0),
        context = canvasDom.getContext('2d');        
        
    ujs.define('img', 'ujs.browser', {
        /**
         * 获取图片文件对象.  
         */
        getFileFromBase64 : function(base64Str, imgType){
            return base64.toFile(base64Str, imgType || 'image/png');
        },
        getThumbnail : function(config, cb){
            var _this = this;
            var image = new Image(); 
            var deferred = $.Deferred();
            image.onload = function() {
                var thumbnailBase64 = ujs.browser.img.getBase64Image(image, config['width'], config['height'], config['type']);
                if(Type.isFunction(cb)){                    
                    if(config['isGetImgFileObj']){
                        //deferred.resolve(this.width, this.height, this);                                                                
                        cb.call(config, _this.getFileFromBase64(thumbnailBase64['value']), thumbnailBase64['value'], config['src'], thumbnailBase64);
                    } else {
                        cb.call(config, thumbnailBase64['value'], config['src'], thumbnailBase64);        
                    }
                }
            };
            image.src = config['src'];
            return deferred;
        },
        /**
         * 生成缩略图. 
         */
        genThumbnail : function(config, cb){   
            var _this = this;         
            if(config['async'] === false){
                var image = new Image();  
                //若图片地址为base64字符串.
                image.src = config['src'];
                var thumbnailBase64 = ujs.browser.img.getBase64Image(image, config['width'], config['height'], config['type']);
                
                var imageInfo = {
                    base64 : thumbnailBase64['value']
                };
                if(config['isGetImgFileObj']){
                    imageInfo['file'] = _this.getFileFromBase64(thumbnailBase64['value']);
                }
                return imageInfo;
            } else {   
                var imageFile = config['src'];
                if(Type.isString(imageFile)){   //file url
                    _this.getThumbnail(config, cb);        
                } else {    //file obj
                    var reader = new FileReader();  
                    reader.onload = function(e){                    
                        config['src'] = e.target.result;
                        config['type'] = imageFile.type;
                        _this.getThumbnail(config, cb);
                    };
                    reader.readAsDataURL(imageFile);
                }         
            }
        },
        /**
         * 获取图片的尺寸。 
         * @param {String|File} imgSrc
         * @return {ImageHtmlElement}
         * @return $deferred.
         */
        getSize : function(imgSrc){        
            if(!Type.isString(imgSrc)){
                imgSrc = URL.createObjectURL(imgSrc);
            }
            var imgObj = new Image(),
                deferred = $.Deferred();
                
            imgObj.onload = function() {
                deferred.resolve(this.width, this.height, this);
            };
            imgObj.src = imgSrc;
                
            return deferred;
        },       
        
        /**
         * 合并多张图片. 
         * @param {FileCollection} files
         * @param {Number} colCount
         * @param {Number} width
         * @param {Number} height
         * @param {Number} spacing
         * @param {Function} cb
         */
        merge : function(files, colCount, width, height, spacing, cb){  
            var _this = this;
            files = Object.toArray(files).filter(function(file){
                return ujs.browser.file.isImage(file);
            });         
            var canvas = $('<canvas></canvas>').get(0);
            var ctx = canvas.getContext('2d');
            
            var filesCount = files.length;
            var rowCount = Math.ceil(filesCount / colCount);
            var totalWidth = width + spacing;
            var totalHeight = height + spacing;
            
            canvas.width = colCount * totalWidth - spacing;         
            canvas.height = rowCount * totalHeight - spacing;            
            
            var handleCount = 0;
            for(var i=0; i<filesCount; i++){
                var file = files[i];
                (function(i){       
                    _this.genThumbnail({
                        src : file,                        
                        width : width,
                        height : height,
                        isGetImgFileObj : true
                    },
                    function(thumbImgFile, thumbnailBase64Str, originalFileBase64Str){
                        
                        ujs.browser.file.toImage(thumbImgFile, function(image){
                            ctx.drawImage(
                                image, 
                                Math.floor(i % colCount) * totalWidth + (width - image.width)/2, 
                                Math.floor(i / colCount) * totalHeight + (height - image.height)/2, 
                                image.width, 
                                image.height
                            );
                            handleCount++;
                            if(handleCount == filesCount){
                                cb && cb(canvas.toDataURL('image/png'));
                            }   
                        });
                    });
                })(i);                   
            }
        },
        /**
         *  获取已加载图片的base64格式.  
         * @param {Object} image
         * @param {Object} imgWidth
         * @param {Object} imgHeight
         * @param {Object} imgType
         */       
        getBase64Image : function(image, imgWidth, imgHeight, imgType){        
            Size.constraint(image, imgWidth, imgHeight);        
            var width = image.width,
                height = image.height,
                newWidth,
                newHeight;
                            
            if(Type.isNumber(width) && Type.isNumber(height)){
                newWidth = width;
                newHeight = height;
            } else {
                var scale = 0.2;
                if(Type.isNumber(width)){
                    if(width > image.width){
                        scale = 1;
                    } else {
                        scale = width / image.width;
                    }
                } else if(Type.isNumber(height)){
                    if(height > image.height){
                        scale = 1;
                    } else {
                        scale = height / image.height;
                    }
                }
                newWidth = image.width * scale;
                newHeight = image.height * scale;
            }                                
            canvasDom.width = newWidth;
            canvasDom.height = newHeight;            
            context.drawImage(image, 0, 0, newWidth, newHeight);     
               
            return {
                value : canvasDom.toDataURL(imgType),
                width : newWidth,
                height : newHeight    
            };
        }
    })    
})($);